<?php
/**
 * 函数式编程
 *
 * @author dogstar 20161113
 */


class Functional_Lite {

    protected $data;

    public function __construct($data) {
        $this->data = $data;
    }


    /** ------------ middle operation ------------ **/

    public function filter($callback) {
        $newData = array();

        if (!is_callable($callback)) {
            $callback = create_function('$it', 'return ' . $callback . ';');
        }

        foreach ($this->data as $item) {
            if (call_user_func($callback, $item)) {
                $newData[] = $item;
            }
        }

        $this->data = $newData;

        return $this;
    }

    public function map($callback) {
        if (!is_callable($callback)) {
            $callback = create_function('$it', 'return ' . $callback . ';');
        }

        foreach ($this->data as &$itemRef) {
            $itemRef = call_user_func($callback, $itemRef);
        }

        return $this;
    }

    /** ------------ end operation ------------ **/

    public function reduce($callback, $accumulator) {
        $rs = $accumulator;

        if (!is_callable($callback)) {
            $callback = create_function('$it_1, $it_2', 'return ' . $callback . ';');
        }

        foreach ($this->data as $item) {
            $rs = call_user_func_array($callback, array($rs, $item));
        }

        return $rs;
    }


    public function foldLeft($callback, $accumulator = NULL) {
        // default
        if ($accumulator === NULL) {
            $accumulator = array_shift($this->data);
        }

        return $this->reduce($callback, $accumulator);
    }

    public function foldRight($callback, $accumulator = NULL) {
        $this->data = array_reverse($this->data);
        return $this->foldLeft($callback, $accumulator);
    }

    /** ------------ extra operation ------------ **/

}
